package upc.dew.inscripcionalumnos.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import upc.dew.inscripcionalumnos.exception.LoginException;
import upc.dew.inscripcionalumnos.exception.ServiceException;
import upc.dew.inscripcionalumnos.model.Estado;
import upc.dew.inscripcionalumnos.model.Postulante;
import upc.dew.inscripcionalumnos.model.Rol;
import upc.dew.inscripcionalumnos.model.Usuario;

/**
 * 
 * @author andres
 */
public class LoginController extends BaseController
{
    private static final String PARAMETRO_ACCION = "accion";
    private static final String ACCION_LOGIN = "login";
    private static final String ACCION_LOGOUT = "logout";
    private static final String ACCION_REGISTRAR_POSTULANTE = "registrar";

    private String view;

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
            throws Exception
    {
        if (esAccionLogin(request))
        {
            return login(request, response);
        }
        else if (esAccionLogout(request))
        {
            return finalizarSesion(request);
        }
        else if (esAccionRegistrarPostulante(request))
        {
            return registrar(request, response);
        }

        return initialize();
    }

    /**
     * Realiza la acci&oacute;n de login disparada desde el formulario de login.
     * 
     * @param request
     * @param response
     * @return
     */
    private ModelAndView login(HttpServletRequest request, HttpServletResponse response)
    {
        // Se obtiene parametros del jsp
        String username = request.getParameter("usuario");
        String password = request.getParameter("password");

        try
        {
            Usuario usuario = getLoginService().login(username, password);
            iniciarSesion(request, usuario);

            // Se evalua el rol del usuario autenticado
            if (usuario.getRol().isOfType(Rol.POSTULANTE))
            {
                return new ModelAndView(new RedirectView("postulante.do"));
            }
            else if (usuario.getRol().isOfType(Rol.EVALUADOR))
            {
                return new ModelAndView(new RedirectView("evaluador.do?accion=listarPostulantes"));
            }
            else if (usuario.getRol().isOfType(Rol.ADMINISTRADOR))
            {
                return new ModelAndView(new RedirectView("administrador.do?accion=listarRequisitos"));
            }
            else
            {
                throw new RuntimeException("El Rol '" + usuario.getRol() + "' no es soportado.");
            }
        }
        catch (LoginException e)
        {
            // No se pudo autenticar al usuario. Redireccionar a la pagina
            // inicial.
        }
        catch (ServiceException e)
        {
            // Redireccionar a la pagina inicial y mostrar un error.
        }

        return new ModelAndView(view);
    }

    /**
     * Realiza la acci&oacute;n de registro de nuevo postulante disparada desde el formulario de login.
     * 
     * @param request
     * @param response
     * @return
     */
    private ModelAndView registrar(HttpServletRequest request, HttpServletResponse response)
    {
        Map<String, Object> model = new HashMap<String, Object>();

        Postulante postulante = new Postulante();
        postulante.setUsername(request.getParameter("correo"));
        postulante.setPassword(request.getParameter("newpassword"));
        postulante.setApellidoPaterno(request.getParameter("apellidoPaterno"));
        postulante.setApellidoMaterno(request.getParameter("apellidoMaterno"));
        postulante.setNombre(request.getParameter("nombre"));
        postulante.setSexo(Integer.parseInt(request.getParameter("sexo")));
        postulante.setFase(1);
        postulante.setEstado(Estado.PENDIENTE);
        postulante.setRol(Rol.POSTULANTE);

        String fechaNacimiento = request.getParameter("anio_nacimiento").concat("-").
                concat(request.getParameter("mes_nacimiento")).concat("-").concat(request.getParameter("dia_nacimiento"));

        postulante.setFechaNacimiento(safeParseDate(fechaNacimiento));

        Usuario usuario = getPostulanteService().registrarUsuario(postulante);
        postulante.setCodigo(usuario.getCodigo());
        postulante = getPostulanteService().registrarPostulante(postulante);

        createFilesDirectory(postulante.getCodigoPostulante() + "-" + postulante.getApellidoPaterno().concat(postulante.getApellidoMaterno()));

        iniciarSesion(request, postulante);
        return new ModelAndView(new RedirectView("postulante.do"));
    }

    private ModelAndView initialize() throws ServiceException
    {
        Map<String, Object> model = new HashMap<String, Object>();
        model.put("generos", getCatalogoService().obtenerGeneros());
        
        return new ModelAndView(view, model);
    }

    /**
     * Realiza el inicio de sesi&oacute;n para el usuario autenticado.
     * 
     * @param request
     * @param usuario
     */
    private void iniciarSesion(HttpServletRequest request, Usuario usuario)
    {
        request.getSession(true);
        request.getSession().setAttribute("usuario", usuario);
    }

    /**
     * Realiza el fin de sesi&oacute;n para el usuario autenticado.
     * 
     * @param request
     * @return
     */
    private ModelAndView finalizarSesion(HttpServletRequest request)
    {
        request.getSession().invalidate();
        return new ModelAndView(new RedirectView("login.do"));
    }

    private boolean esAccionLogin(HttpServletRequest request)
    {
        return ACCION_LOGIN.equals(request.getParameter(PARAMETRO_ACCION));
    }

    private boolean esAccionLogout(HttpServletRequest request)
    {
        return ACCION_LOGOUT.equals(request.getParameter(PARAMETRO_ACCION));
    }

    private boolean esAccionRegistrarPostulante(HttpServletRequest request)
    {
        return ACCION_REGISTRAR_POSTULANTE.equals(request.getParameter(PARAMETRO_ACCION));
    }

    /**
     * Metodo utilizado por el framework para inicializar el objeto view.
     * 
     * @param view
     */
    public void setView(String view)
    {
        this.view = view;
    }
}
